// ***********************************************************************
// Provided for Informational Purposes Only
//
// Apache 2.0 License
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may
// not use this file except in compliance with the License. You may obtain
// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY 
// IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR 
// PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing
// permissions and limitations under the License.
// ***********************************************************************
// Assembly  : ContractMeow.Data.WinRT
// File      : AuthRepository.cs
//
// ***********************************************************************
using ContractMeow.Api.Clients;
using ContractMeow.Data.WinRT.Models;
using ContractMeow.Models;
using System;
using System.Net;
using System.Threading.Tasks;

namespace ContractMeow.Data.WinRT.Api
{
	/// <summary>
	/// Provides access to authorization and permission related things via the Yammer Api.
	/// </summary>
	public sealed class AuthRepository : BaseRepository, IAuthRepository
	{
		/// <summary>
		/// Auth api client for doing all the actual work.
		/// </summary>
		private readonly IAuthClient _authClient;

		private readonly IUserRepository _userRepository;

		public AuthRepository(IStateManager stateManager, IAuthClient authClient, IUserRepository userRepository)
			: base(stateManager)
		{
			this._userRepository = userRepository;
			this._authClient = authClient;
		}

		private async Task<Credentials> GetCredentialsAsync(String username, String password)
		{
			var apiPrincipal = await _authClient.GetPrincipalAsync(username, password);
			return apiPrincipal == null ? null : new Credentials(apiPrincipal);
		}

		/// <summary>
		/// Hydrates the credentials async.
		/// </summary>
		/// <param name="token">The token.</param>
		/// <returns>Task{ICredentials}.</returns>
		public async Task<Credentials> HydrateCredentialsAsync(String token)
		{
			var accessToken = await _authClient.HydrateTokenAsync(token);

			return accessToken == null
					   ? null
					   : new Credentials
						   {
							   AuthToken = new Token
								   {
									   AuthenticatedAt = accessToken.AuthorizedAt,
									   ExpiresAt = accessToken.ExpiresAt,
									   Key = accessToken.Token
								   },
							   NetworkId = accessToken.NetworkId,
							   UserId = accessToken.UserId,
						   };
		}

		public async Task<Credentials> LoginAsync(String username, String password)
		{
			var credentials = await GetCredentialsAsync(username, password);

			if (credentials != null)
			{
				_stateManager.Credentials = credentials;
				_stateManager.CurrentUser = null;
				_stateManager.CurrentUser = await _userRepository.GetCurrentUserAsync();
			}

			return credentials;
		}

		/// <summary>
		/// Uses existing authorization from a prior login
		/// </summary>
		/// <param name="credentials">existing credentials from a prior authorization</param>
		public void Login(Credentials credentials)
		{
			_stateManager.Credentials = credentials;
		}

		/// <summary>
		/// Removes the stored user credentials, if there is one.
		/// </summary>
		public void Logout()
		{
			_stateManager.Credentials = null;
		}

		public CookieContainer CookieContainer
		{
			get { return _authClient.CookieStore.CookieContainer; }
		}
	}
}